package com.jprocms.module.cms.job;

import cn.hutool.core.date.DateUtil;
import com.jpro.framework.tenant.core.context.TenantContextHolder;
import com.jprocms.module.cms.dal.dataobject.content.ContentDO;
import com.jprocms.module.cms.dal.mysql.content.ContentMapper;
import com.jprocms.module.cms.dto.JobDto;
import com.jprocms.module.cms.enums.EnumContentStatus;
import com.jprocms.module.cms.enums.EnumJobStatus;
import com.jprocms.module.cms.enums.EnumJobType;
import com.jprocms.module.cms.framework.job.util.XxlJobUtil;
import com.jprocms.module.cms.service.job.JobService;
import com.jprocms.module.cms.util.CronUtil;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

import static com.jprocms.module.cms.constant.CmsSysConstants.DEF_TOP_LEVEL;
import static com.jprocms.module.cms.constant.JobConstant.*;

@Slf4j
@Service
public class ContentJobServiceImpl implements ContentJobService {

    public void createScheduleTask(ContentDO contentDO) {
        Date topStartTime = contentDO.getExt().getTopStartTime();
        //置顶开始晚于现在才创建任务
        if (topStartTime != null && DateUtil.compare(topStartTime, DateUtil.date()) > 0) {
            JobDto job = new JobDto();
            job.setJobName(String.format("内容置顶%s,ID:%s", contentDO.getTitle(), contentDO.getId()));
            job.setJobType(EnumJobType.CONTENT_TOP.getCode());
            job.setDataId(contentDO.getId());
            job.setStatus(EnumJobStatus.RUNABLE.getCode());
            job.setParams(contentDO.getId().toString());
            job.setCron(CronUtil.date2Cron(topStartTime, CronUtil.CRON_DATE));
            job.setJobHandler(JOB_HANDLER_CONTENT_UP);
            jobService.addOrUpdateJob(job);
        }
        Date topEndTime = contentDO.getExt().getTopEndTime();
        if (topEndTime != null && DateUtil.compare(topEndTime, DateUtil.date()) > 0) {
            JobDto job = new JobDto();
            job.setJobName(String.format("内容取消置顶%s,ID:%s", contentDO.getTitle(), contentDO.getId()));
            job.setJobType(EnumJobType.CONTENT_TOP_CANCEL.getCode());
            job.setDataId(contentDO.getId());
            job.setStatus(EnumJobStatus.RUNABLE.getCode());
            job.setParams(contentDO.getId().toString());
            job.setCron(CronUtil.date2Cron(topEndTime, CronUtil.CRON_DATE));
            job.setJobHandler(JOB_HANDLER_CONTENT_UP_CACEL);
            jobService.addOrUpdateJob(job);
        }
        Date onlineTime = contentDO.getExt().getOnlineTime();
        if (onlineTime != null && DateUtil.compare(onlineTime, DateUtil.date()) > 0) {
            JobDto job = new JobDto();
            job.setJobName(String.format("内容预约发布%s,ID:%s", contentDO.getTitle(), contentDO.getId()));
            job.setJobType(EnumJobType.CONTENT_PUBLISH.getCode());
            job.setDataId(contentDO.getId());
            job.setStatus(EnumJobStatus.RUNABLE.getCode());
            job.setParams(contentDO.getId().toString());
            job.setCron(CronUtil.date2Cron(onlineTime, CronUtil.CRON_DATE));
            job.setJobHandler(JOB_HANDLER_CONTENT_PUBLISH);
            jobService.addOrUpdateJob(job);
        }

        Date offlineTime = contentDO.getExt().getOfflineTime();
        if (offlineTime != null && DateUtil.compare(offlineTime, DateUtil.date()) > 0) {
            JobDto job = new JobDto();
            job.setJobName(String.format("内容预约下线%s,ID:%s", contentDO.getTitle(), contentDO.getId()));
            job.setJobType(EnumJobType.CONTENT_OFFLINE.getCode());
            job.setDataId(contentDO.getId());
            job.setStatus(EnumJobStatus.RUNABLE.getCode());
            job.setParams(contentDO.getId().toString());
            job.setCron(CronUtil.date2Cron(offlineTime, CronUtil.CRON_DATE));
            job.setJobHandler(JOB_HANDLER_CONTENT_OFFLINE);
            jobService.addOrUpdateJob(job);
        }

    }

    @XxlJob(JOB_HANDLER_CONTENT_UP)
    public void contentTop() {
        String param = XxlJobUtil.getBussinessParam();
        log.info("创建内容置顶任务，参数：{}", param);
        if (!StringUtils.isNumeric(param)) {
            log.error("内容置顶：{} 错误，定时任务执行失败", param);
            return;
        }
        Long contentId = Long.valueOf(param);
        //定时任务这里查询数据忽略租户条件
        TenantContextHolder.setIgnore(true);
        ContentDO content = contentMapper.selectById(contentId);
        if (content == null) {
            log.error("id为：{}不存在，定时任务执行失败", contentId);
            return;
        }
        ContentDO contentDOUpdate = new ContentDO();
        contentDOUpdate.setId(content.getId());
        //暂时定时置顶级别
        contentDOUpdate.setTopLevel(DEF_TOP_LEVEL);
        contentMapper.updateById(contentDOUpdate);
        //执行完成后删除
        jobService.deleteByJobTypeAndDataId(EnumJobType.CONTENT_TOP.getCode(), contentId);
    }

    @XxlJob(JOB_HANDLER_CONTENT_UP_CACEL)
    public void contentTopCacel() {
        String param = XxlJobUtil.getBussinessParam();
        log.info("创建内容取消置顶任务，参数：{}", param);
        if (!StringUtils.isNumeric(param)) {
            log.error("内容取消置顶：{} 错误，定时任务执行失败", param);
            return;
        }
        Long contentId = Long.valueOf(param);
        //定时任务这里查询数据忽略租户条件
        TenantContextHolder.setIgnore(true);
        ContentDO content = contentMapper.selectById(contentId);
        if (content == null) {
            log.error("id为：{}不存在，定时任务执行失败", contentId);
            return;
        }
        ContentDO contentDOUpdate = new ContentDO();
        contentDOUpdate.setId(content.getId());
        contentDOUpdate.setTopLevel(0);
        contentMapper.updateById(contentDOUpdate);
        //执行完成后删除
        jobService.deleteByJobTypeAndDataId(EnumJobType.CONTENT_TOP_CANCEL.getCode(), contentId);
    }

    @XxlJob(JOB_HANDLER_CONTENT_PUBLISH)
    public void contentPublish() {
        String param = XxlJobUtil.getBussinessParam();
        log.info("创建内容发布任务，参数：{}", param);
        if (!StringUtils.isNumeric(param)) {
            log.error("内容发布：{} 错误，定时任务执行失败", param);
            return;
        }
        Long contentId = Long.valueOf(param);
        //定时任务这里查询数据忽略租户条件
        TenantContextHolder.setIgnore(true);
        ContentDO content = contentMapper.selectById(contentId);
        if (content == null) {
            log.error("id为：{}不存在，定时任务执行失败", contentId);
            return;
        }
        ContentDO contentDOUpdate = new ContentDO();
        contentDOUpdate.setId(content.getId());
        contentDOUpdate.setStatus(EnumContentStatus.PUBLISHED.getStatus());
        contentMapper.updateById(contentDOUpdate);
        //执行完成后删除
        jobService.deleteByJobTypeAndDataId(EnumJobType.CONTENT_PUBLISH.getCode(), contentId);
    }

    @XxlJob(JOB_HANDLER_CONTENT_OFFLINE)
    public void contentOffline() {
        String param = XxlJobUtil.getBussinessParam();
        log.info("创建内容下线任务，参数：{}", param);
        if (!StringUtils.isNumeric(param)) {
            log.error("内容下线：{} 错误，定时任务执行失败", param);
            return;
        }
        Long contentId = Long.valueOf(param);
        //定时任务这里查询数据忽略租户条件
        TenantContextHolder.setIgnore(true);
        ContentDO content = contentMapper.selectById(contentId);
        if (content == null) {
            log.error("id为：{}不存在，定时任务执行失败", contentId);
            return;
        }
        ContentDO contentDOUpdate = new ContentDO();
        contentDOUpdate.setId(content.getId());
        contentDOUpdate.setStatus(EnumContentStatus.OFFLINE.getStatus());
        contentMapper.updateById(contentDOUpdate);
        //执行完成后删除
        jobService.deleteByJobTypeAndDataId(EnumJobType.CONTENT_OFFLINE.getCode(), contentId);
    }

    @Resource
    private JobService jobService;
    @Resource
    private ContentMapper contentMapper;
}
